package DARP;

import java.util.LinkedList;

import javax.jws.Oneway;

public class FuncaoObjetivo {


	float funcaoObjetivo;
	float w0,w1,w2,w3,w4,b0,b1,b2,b3,b4;
	Data data;
	float[] R_TempoMaximo_Rota, W_TempoMaximo_Espera, e, l;
	float[][] matrizDistancia = data.getMatriz();//, t;
	int qntVeiculos = data.getQuantidadeDeVeiculos(), qntPontos = data.getQuantidadeDePontosDeColetas();
	int[][][] x = new int[qntVeiculos][qntPontos][qntPontos];
	int[] garagemInicial, garagemFinal;


	/*
	 * ==================================================Calculo da Funcao Objetivo ============================================================
	 */
	//	float funcaoObjetivo;
	//	float w0,w1,w2,w3,w4,b0,b1,b2,b3,b4;
	//	//Data data;
	//	float[] R_TempoMaximo_Rota, W_TempoMaximo_Espera, e, l;
	//	float[][] matrizDistancia = data.getMatriz(), t;
	//	int qntVeiculos = data.getQuantidadeDeVeiculos(), qntPontos = data.getQuantidadeDePontosDeColetas();
	//	int[][][] x = new int[qntVeiculos][qntPontos][qntPontos];
	//	int[] garagemInicial = data.getGaragensIniciais(), garagemFinal = data.getGaragensFinais();

	int[] rota;

	float[] A = new float[qntPontos], 
	B = new float[qntPontos],
	D = new float[qntPontos],
	R = new float[qntPontos],
	W = new float[qntPontos],
	T = new float[qntPontos],
	Q = new float[qntPontos],
	s = new float[qntPontos],
	q = new float[qntPontos];


	public FuncaoObjetivo(Data data) {
		this.data = data;
	}

	private void inicializaVariaveis(){
		for (int k = 0; k < qntVeiculos; k++) {
			A[garagemInicial[k]] =  0;
			D[garagemFinal[k]] =  0; 
			W[garagemInicial[k]] =  0;
			Q[garagemInicial[k]] =  0;
			Q[garagemFinal[k]] =  0;
		}
	}

	/*
	 * Ai
	 */
	private float[] calculaAi(){

		//for (int k = 0; k < qntVeiculos; k++) {
		for (int i = 0; i < qntPontos; i++) {
			//A[]
		}



		return A;
	}



	public float calculaFO(int rota[]){//LinkedList<int[]> lista2
		this.rota = rota;
		return funcaoObjetivo =termoUmUm() + w1*termoUmDois()+termoUmTres()+termoUmQuatro()+termoUmCinco();

	}


	public float termoUmUm(){
		float soma = 0;
		//		for (int i = 0; i < qntPontos; i++) {
		//			System.out.println("Elemento "+i);
		//			for (int j = 0; j < qntPontos; j++) {
		//				System.out.println("("+i+"," +j+")"+matrizDistancia[i][j]);
		//			}
		//		}
//		for (int k = 0; k < qntVeiculos; k++) {
//			int[] rotaDaVez = lista.get(k);
			//System.out.println("K = "+k);
			//for (int i = 0; i < qntPontos; i++) {
			int i = 0;
			while(i < qntVeiculos){	
				System.out.println("FO 1 1 : ("+rota[i]+"," +rota[i+1]+")");
				soma += matrizDistancia[rota[i]][rota[i+1]];
				i++;
			}
			//	
			//}
//		}
		System.out.println("Termo 1 1 = "+ soma);
		return soma;
	}

	public float termoUmDois(){
		float soma = 0;
		//for (int k = 0; k < qntVeiculos; k++) {
		//	int[] rotaDaVez = rota;
		//	if(rotaDaVez.length > 2)
		soma += 1 ;
		//		}
		System.out.println("Termo 1 2 = "+ soma);
		return soma;
	}

	public float termoUmTres(){
		float soma = 0;
		for (int k = 0; k < qntVeiculos; k++) {
			//for (int i = 0; i < qntPontos; i++) {
			//for (int j = 0; j < qntPontos; j++) {
			soma += B[garagemInicial[k]] - D[garagemInicial[k]];
			//				}
			//}
		}
		return soma;
	}

	public float termoUmQuatro(){
		float soma = 0;
		for (int i = 0; i < qntPontos/2; i++) {
			soma += R[i];
		}
		return soma;
	}

	public float termoUmCinco(){
		float soma = 0;
		//for (int k = 0; k < qntVeiculos; k++) {
		for (int i = 1; i < qntPontos-1; i++) {
			//for (int j = 0; j < qntPontos; j++) {
			soma += W[i];
			//				}
			//}
		}
		return soma;
	}

	public float termoDoisUm(){
		float soma = 0;
		for (int k = 0; k < qntVeiculos; k++) {
			soma += Math.max(0, B[garagemInicial[k]] - D[garagemInicial[k]] - T[k]);//TODO T"[k]

		}
		return soma;
	}

	public float termoDoisDois(){
		float soma = 0;
		for (int i = 0; i < qntPontos/2; i++) {
			soma += Math.max(0, R[i] - R_TempoMaximo_Rota[i]);//TODO T"[k]

		}
		return soma;
	}

	public float termoDoisTres(){
		float soma = 0;
		for (int i = 1; i < qntPontos - 1; i++) {
			soma += Math.max(0, W[i] - W_TempoMaximo_Espera[i]);//TODO T"[k]

		}
		return soma;
	}

	//TODO REFERE-SE A CARGA DO VEICULO!!! FAZER!!! 
	public float termoDoisQuatro(){
		float soma = 0;
		for (int i = 1; i < qntPontos - 1; i++) {
			soma += Math.max(0, Q[i]);//TODO FAZER CARGA 

		}
		return soma;
	}

	public float termoDoisCinco(){
		float soma = 0;
		for (int i = 1; i < qntPontos - 1; i++) {
			soma += Math.max(0, e[i] - B[i])+ Math.max(0, B[i] - l[i]);//TODO FAZER CARGA 

		}
		return soma;
	}

	/*
	 * Sujeito a:
	 */

	//	public int restricaoUm(){
	//		int soma = 0;
	//		for (int k = 0; k < qntVeiculos; k++) {
	//			for (int j = 1; j < qntPontos-1; j++) {
	//				soma +=  x[k][garagemInicial[k]][j];	
	//			}
	//		}
	//		return 0;
	//	}


	//TODO IMPLEMENTAR O RESTANTE !!

	public float[] atrasoInicioServico(){//Passar os parametros){
		int soma = 0;
		for (int i = 0; i < qntPontos; i++) {
			for (int j = 0; j < qntPontos; j++) {
				for (int k = 0; k < qntVeiculos; k++) {
					soma = x[k][i][j]; 					
				}
				B[j] = ((B[i] + s[i]+matrizDistancia[i][j]/20+W[j])*soma);
			}	
		}
		return B;
	}

	public float[] calculaCarga(){
		int soma = 0;
		for (int i = 0; i < qntPontos; i++) {
			for (int j = 0; j < qntPontos; j++) {
				for (int k = 0; k < qntVeiculos; k++) {
					soma = x[k][i][j]; 					
				}
				Q[j] = (Q[i]+ q[j])*soma;
			}	
		}
		return Q;
	}

	public float[] calculaTempoDeChegada(){

		for (int i = 0; i < qntPontos; i++) {
			A[i] = (B[i]- W[i]);
		}
		return A;
	}

	public float[] calculaTempoDePartida(){
		for (int i = 0; i < qntPontos; i++) {
			D[i] = (B[i] + s[i]);
		}
		return D;
	}

	public float[] calculaTempoDeViagem(){
		for (int i = 0; i < qntPontos; i++) {
			R[i] = (B[(qntPontos/2) + i] + s[i]);
		}
		return R;
	}







	//	===========================================================================================================================
	//	float[] A = new float[qntPontos], 
	//	B = new float[qntPontos],
	//	D = new float[qntPontos],
	//	R = new float[qntPontos],
	//	W = new float[qntPontos],
	//	T = new float[qntPontos],
	//	Q = new float[qntPontos],
	//	s = new float[qntPontos],
	//	q = new float[qntPontos];
	//
	//
	//	private void inicializaVariaveis(){
	//		A[garagemInicial] =  0;
	//		D[garagemFinal] =  0; 
	//		W[garagemInicial] =  0;
	//		Q[garagemInicial] =  0;
	//		Q[garagemFinal] =  0;
	//
	//	}
	//
	//	public float calculaFO(){
	//		funcaoObjetivo =w0*termoUmUm() + w1*termoUmDois();
	//		return 0;
	//	}
	//
	//
	//	public float termoUmUm(){
	//		float soma = 0;
	//		for (int k = 0; k < qntVeiculos; k++) {
	//			for (int i = 0; i < qntPontos; i++) {
	//				for (int j = 0; j < qntPontos; j++) {
	//					if(i!=j)
	//						soma += matrizDistancia[i][j]*x[k][i][j];
	//				}
	//			}
	//		}
	//
	//		return soma;
	//	}
	//
	//	public float termoUmDois(){
	//		float soma = 0;
	//		for (int k = 0; k < qntVeiculos; k++) {
	//			//for (int i = 0; i < qntPontos; i++) {
	//			for (int j = 0; j < qntPontos/2; j++) {
	//				soma += x[k][garagemInicial[k]][j];
	//				//				}
	//			}
	//		}
	//		return soma;
	//	}
	//
	//	public float termoUmTres(){
	//		float soma = 0;
	//		for (int k = 0; k < qntVeiculos; k++) {
	//			//for (int i = 0; i < qntPontos; i++) {
	//			//for (int j = 0; j < qntPontos; j++) {
	//			soma += B[garagemInicial[k]] - D[garagemInicial[k]];
	//			//				}
	//			//}
	//		}
	//		return soma;
	//	}
	//
	//	public float termoUmQuatro(){
	//		float soma = 0;
	//		for (int i = 0; i < qntPontos/2; i++) {
	//			soma += R[i];
	//		}
	//		return soma;
	//	}
	//
	//	public float termoUmCinco(){
	//		float soma = 0;
	//		//for (int k = 0; k < qntVeiculos; k++) {
	//		for (int i = 1; i < qntPontos-1; i++) {
	//			//for (int j = 0; j < qntPontos; j++) {
	//			soma += W[i];
	//			//				}
	//			//}
	//		}
	//		return soma;
	//	}
	//
	//	public float termoDoisUm(){
	//		float soma = 0;
	//		for (int k = 0; k < qntVeiculos; k++) {
	//			soma += Math.max(0, B[garagemInicial[k]] - D[garagemInicial[k]] - T[k]);//TODO T"[k]
	//
	//		}
	//		return soma;
	//	}
	//
	//	public float termoDoisDois(){
	//		float soma = 0;
	//		for (int i = 0; i < qntPontos/2; i++) {
	//			soma += Math.max(0, R[i] - R_TempoMaximo_Rota[i]);//TODO T"[k]
	//
	//		}
	//		return soma;
	//	}
	//
	//	public float termoDoisTres(){
	//		float soma = 0;
	//		for (int i = 1; i < qntPontos - 1; i++) {
	//			soma += Math.max(0, W[i] - W_TempoMaximo_Espera[i]);//TODO T"[k]
	//
	//		}
	//		return soma;
	//	}
	//
	//	//TODO REFERE-SE A CARGA DO VEICULO!!! FAZER!!! 
	//	public float termoDoisQuatro(){
	//		float soma = 0;
	//		for (int i = 1; i < qntPontos - 1; i++) {
	//			soma += Math.max(0, Q[i]);//TODO FAZER CARGA 
	//
	//		}
	//		return soma;
	//	}
	//
	//	public float termoDoisCinco(){
	//		float soma = 0;
	//		for (int i = 1; i < qntPontos - 1; i++) {
	//			soma += Math.max(0, e[i] - B[i])+ Math.max(0, B[i] - l[i]);//TODO FAZER CARGA 
	//
	//		}
	//		return soma;
	//	}
	//
	//	/*
	//	 * Sujeito a:
	//	 */
	//
	//	public int restricaoUm(){
	//		int soma = 0;
	//		for (int k = 0; k < qntVeiculos; k++) {
	//			for (int j = 1; j < qntPontos-1; j++) {
	//				soma +=  x[k][garagemInicial[k]][j];	
	//			}
	//		}
	//		return 0;
	//	}
	//
	//
	//	//TODO IMPLEMENTAR O RESTANTE !!
	//
	//	public float[] atrasoInicioServico(){//Passar os parametros){
	//		int soma = 0;
	//		for (int i = 0; i < qntPontos; i++) {
	//			for (int j = 0; j < qntPontos; j++) {
	//				for (int k = 0; k < qntVeiculos; k++) {
	//					soma = x[k][i][j]; 					
	//				}
	//				B[j] = ((B[i] + s[i]+t[i][j]+W[j])*soma);
	//			}	
	//		}
	//		return B;
	//	}
	//
	//	public float[] calculaCarga(){
	//		int soma = 0;
	//		for (int i = 0; i < qntPontos; i++) {
	//			for (int j = 0; j < qntPontos; j++) {
	//				for (int k = 0; k < qntVeiculos; k++) {
	//					soma = x[k][i][j]; 					
	//				}
	//				Q[j] = (Q[i]+ q[j])*soma;
	//			}	
	//		}
	//		return Q;
	//	}
	//
	//	public float[] calculaTempoDeChegada(){
	//
	//		for (int i = 0; i < qntPontos; i++) {
	//			A[i] = (B[i]- W[i]);
	//		}
	//		return A;
	//	}
	//
	//	public float[] calculaTempoDePartida(){
	//		for (int i = 0; i < qntPontos; i++) {
	//			D[i] = (B[i] + s[i]);
	//		}
	//		return D;
	//	}
	//
	//	public float[] calculaTempoDeViagem(){
	//		for (int i = 0; i < qntPontos; i++) {
	//			R[i] = (B[(qntPontos/2) + i] + s[i]);
	//		}
	//		return R;
	//	}


}
